package frame.usermeau.service.serviceimpl;

import frame.model.SnowflakeIdWorker;
import frame.usermeau.service.ServiceFrame;
import it.unimi.dsi.fastutil.Hash;
import tech.tablesaw.api.StringColumn;
import tech.tablesaw.api.Table;

import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.math.BigDecimal;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class FundServiceFrame extends ServiceFrame {

    private String userId;

    /**
     * 显示导航栏，固定不改变
     * @return
     */
    @Override
    public JPanel showOptions() {
        JPanel jPanel = new JPanel(null);
        JLabel jl;

        //类型
        jl = new JLabel("类型:");
        jl.setSize(80,20);
        jl.setLocation(30,20);
        jPanel.add(jl);
        JComboBox category = new JComboBox();
        category.addItem("请选择基金类型");
        category.addItem("货币型");
        category.addItem("债券型");
        category.addItem("混合型");
        category.addItem("指数型");
        category.addItem("股票型");
        category.setSize(100,20);
        category.setLocation(80,20);
        jPanel.add(category);

        //风险等级
        jl = new JLabel("风险等级:");
        jl.setSize(80,20);
        jl.setLocation(230,20);
        jPanel.add(jl);
        JComboBox riskRank = new JComboBox();
        riskRank.addItem("请选择风险等级");
        riskRank.addItem("R1");
        riskRank.addItem("R2");
        riskRank.addItem("R3");
        riskRank.addItem("R4");
        riskRank.addItem("R5");
        riskRank.setSize(100,20);
        riskRank.setLocation(300,20);
        jPanel.add(riskRank);

        //名称
        jl = new JLabel("名称:");
        jl.setSize(80,20);
        jl.setLocation(430,20);
        jPanel.add(jl);
        JTextArea inputName = new JTextArea();
        inputName.setSize(150,20);
        inputName.setLocation(500,20);
        jPanel.add(inputName);

        //确认按钮
        JButton jButton = new JButton("确认");
        jButton.setSize(60,40);
        jButton.setLocation(600,50);
        jPanel.add(jButton);

        //结果框
        JTextArea result = new JTextArea();
        result.setSize(400, 500);
        result.setLocation(30,100);
        jPanel.add(result);

        padding(result);

        jButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                String name = inputName.getText();
                Table strs;
                if(name.length() == 0) {
                    strs = showMessage(category.getSelectedItem().toString(),
                            riskRank.getSelectedItem().toString(), "");
                }else {
                    strs = showMessage(category.getSelectedItem().toString(),
                            riskRank.getSelectedItem().toString(), name);
                }
                result.setText("");
                result.setText(strs.print());
            }
        });
        return jPanel;
    }

    public void padding(JTextArea jTextArea) {
        init();
        Table table = null;

        List<String> fundIdList = new ArrayList<>();
        List<String> fundNameList = new ArrayList<>();
        List<String> fundTypeList = new ArrayList<>();
        List<String> fundRiskList = new ArrayList<>();
        try {
            PreparedStatement preparedStatement = conn.prepareStatement("select fu_id,fu_name,fu_type,fu_risk,fu_is_on_sale from t_fund");
            ResultSet resultSet = preparedStatement.executeQuery();

            while (resultSet.next()) {
                String fundID = resultSet.getString(1);
                String fundName = resultSet.getString(2);
                String fundType = resultSet.getString(3);
                String fundRisk = "R"+resultSet.getString(4);
                boolean isOnSale = resultSet.getBoolean(5);
                if (isOnSale) {
                    fundIdList.add(fundID);
                    fundNameList.add(fundName);
                    fundTypeList.add(fundType);
                    fundRiskList.add(fundRisk);
                }
            }
            table = Table.create("相关基金").addColumns(
                    StringColumn.create("基金ID",fundIdList),
                    StringColumn.create("基金名称",fundNameList),
                    StringColumn.create("基金类型",fundTypeList),
                    StringColumn.create("基金风险等级",fundRiskList)
            );
            jTextArea.setText(table.print());
            resultSet.close();
            preparedStatement.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 返回结果
     * @param type 类型
     * @param risk 风险等级
     * @param name 名称，可以为空字符串
     */
    private Table showMessage(String type, String risk, String name) {
        init();
        Table table = null;

        List<String> fundIdList = new ArrayList<>();
        List<String> fundNameList = new ArrayList<>();
        List<String> fundTypeList = new ArrayList<>();
        List<String> fundRiskList = new ArrayList<>();


        if ("请选择基金类型".equals(type)) {
            type = "型";
        }
        if ("请选择风险等级".equals(risk)) {
            risk = "6";
        }else{
            risk = risk.substring(1);
        }

        if ("".equals(name)) {
            init();
            try {
                PreparedStatement preparedStatement = conn.prepareStatement("select fu_id, fu_name, fu_type, fu_risk, fu_is_on_sale from t_fund where fu_type like '%'||?||'%' and fu_risk <= ? ;");
                preparedStatement.setString(1,type);
                preparedStatement.setInt(2,Integer.parseInt(risk));
                ResultSet resultSet = preparedStatement.executeQuery();
                while (resultSet.next()) {
                    String fundID = resultSet.getString(1);
                    String fundName = resultSet.getString(2);
                    String fundType = resultSet.getString(3);
                    String fundRisk = "R"+resultSet.getString(4);
                    boolean isOnSale = resultSet.getBoolean(5);
                    if (isOnSale) {
                        fundIdList.add(fundID);
                        fundNameList.add(fundName);
                        fundTypeList.add(fundType);
                        fundRiskList.add(fundRisk);
                    }
                }
                resultSet.close();
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }else{
            try {
                PreparedStatement preparedStatement = conn.prepareStatement("select fu_id, fu_name, fu_type, fu_risk, fu_is_on_sale from t_fund where fu_type like '%'||?||'%' and fu_risk <= ? and fu_name like '%' || ? || '%';");
                preparedStatement.setString(1,type);
                preparedStatement.setInt(2,Integer.parseInt(risk));
                preparedStatement.setString(3,name);
                ResultSet resultSet = preparedStatement.executeQuery();
                while (resultSet.next()) {
                    String fundID = resultSet.getString(1);
                    String fundName = resultSet.getString(2);
                    String fundType = resultSet.getString(3);
                    String fundRisk = "R"+resultSet.getString(4);
                    boolean isOnSale = resultSet.getBoolean(5);
                    if (isOnSale) {
                        fundIdList.add(fundID);
                        fundNameList.add(fundName);
                        fundTypeList.add(fundType);
                        fundRiskList.add(fundRisk);
                    }
                }
                resultSet.close();
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        table = Table.create("相关基金").addColumns(
                StringColumn.create("基金ID",fundIdList),
                StringColumn.create("基金名称",fundNameList),
                StringColumn.create("基金类型",fundTypeList),
                StringColumn.create("基金风险等级",fundRiskList)
        );
        return table;
    }


    /**
     * 购买产品
     * @param fundId    基金ID
     * @param money     购买金额
     */
    @Override
    public void purchase(String fundId, Integer money) {
        fundId = fundId.trim();
        if (isTrueFund(fundId)) {
            // fundId输入无误

            init();
            BigDecimal buy = new BigDecimal(money);
            BigDecimal limit = new BigDecimal(-1000);

            // 卡号和卡里面的钱
            String useCard = null;
            BigDecimal moneyInCard = null;
            try {
                PreparedStatement getAllCards = conn.prepareStatement("select c_id, c_type, c_balance from t_card where c_user_id = ?");
                getAllCards.setString(1, userId);
                ResultSet resultSet = getAllCards.executeQuery();
                while (resultSet.next()) {
                    String cardId = resultSet.getString(1);
                    int typeCard = resultSet.getInt(2);
                    BigDecimal cardMoney = resultSet.getBigDecimal(3);
                    if (typeCard == 0) {
                        // 储蓄卡
                        if (cardMoney.compareTo(buy) >= 0) {
                            useCard = cardId;
                            moneyInCard = cardMoney;
                            break;
                        }
                    }else {
                        // 信用卡
                        if (cardMoney.subtract(buy).compareTo(limit) >= 0) {
                            useCard = cardId;
                            moneyInCard = cardMoney;
                            break;
                        }
                    }
                }
                conn.close();
                getAllCards.close();
                resultSet.close();

                if (useCard == null) {
                    JOptionPane.showMessageDialog(null, "账户金额不足！");
                }else{
                    // 减钱, 购买对应基金
                    init();
                    conn.setAutoCommit(false);

                    PreparedStatement updateCard = conn.prepareStatement("update t_card set c_balance = c_balance - ? where c_id = ? ");
                    PreparedStatement purseFund = conn.prepareStatement("insert into t_fundassets(fua_id, fua_status, fua_amount, fua_income, fua_date, fua_user_id, fua_fund_id) values(?,?,?,?,now(),?,?)");
                    PreparedStatement recordMent = conn.prepareStatement("insert into t_transaction(tra_id, tra_amount, tra_time, tra_card_id) values(?,?,now(),?)");

                    updateCard.setInt(1,buy.intValue());
                    updateCard.setString(2, useCard);

                    purseFund.setString(1, idWorker.nextId() + "22");
                    purseFund.setInt(2,1);
                    purseFund.setBigDecimal(3,buy);
                    purseFund.setBigDecimal(4,new BigDecimal(0));
                    purseFund.setString(5,userId);
                    purseFund.setString(6,fundId);

                    recordMent.setString(1, idWorker.nextId() + "88");
                    recordMent.setDouble(2, buy.doubleValue() * (-1));
                    recordMent.setString(3, useCard);

                    updateCard.executeUpdate();
                    purseFund.execute();
                    recordMent.execute();
                    conn.commit();

                    updateCard.close();
                    purseFund.close();
                    recordMent.close();
                    conn.close();

                    this.dispose();
                }

            } catch (SQLException e) {
                try {
                    conn.rollback();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
                e.printStackTrace();
            }
        }

    }

    public FundServiceFrame(String userId) {
        super();
        this.userId = userId;
    }

    Connection conn;
    SnowflakeIdWorker idWorker;

    public void init() {
        try {
            Class.forName("org.opengauss.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        try {
            conn = DriverManager.getConnection("jdbc:opengauss://121.36.41.207:26000/finance", "geqiyu", "Tlyz0729");

        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            // 设置demo为搜索路径
            PreparedStatement firstStep = conn.prepareStatement("SET SEARCH_PATH TO db1,public");
            firstStep.execute();
            firstStep.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        idWorker = new SnowflakeIdWorker(0, 0);
    }


    public boolean isTrueFund(String fundId) {
        if (fundId.length() != 20) {
            JOptionPane.showMessageDialog(null, "基金ID输入格式不对，请重新输入");
            return false;
        }else{
            init();
            try {
                PreparedStatement preparedStatement = conn.prepareStatement("select fu_id from t_fund where fu_id = ?");
                preparedStatement.setString(1,fundId);
                ResultSet resultSet = preparedStatement.executeQuery();
                if (resultSet.next()) {
                    return true;
                }
                conn.close();
                resultSet.close();
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            JOptionPane.showMessageDialog(null, "没有以此为ID的基金");
            return false;
        }
    }

    public static void main(String[] args) {
        new FundServiceFrame("152");
    }
}
